<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html lang="ru" xml:lang="ru">

<head>
  <meta http-equiv="Content-type" content="text/html; charset=windows-1251" />
  <title>Basis Test Suite - DOM Wrapers</title>

  <style type="text/css">
    @import "style/default/style.css";

    /* */
    BODY
    {
      font-family: Georgia;
      font-size: small;
      _font-size: x-small;
    }
  </style>
  
  <script type="text/javascript"  src="../basis.js"></script>
  <script type="text/javascript"  src="../data.js"></script>
  <script type="text/javascript"  src="../dom_wrapper.js"></script>
  <script type="text/javascript"  src="../property.js"></script>
  <script type="text/javascript"  src="test.js"></script>
  <script type="text/javascript"  src="common.js"></script>
</head>

<body>

  <script type="text/javascript">
    loadTest((function(){

      var Class = Basis.Class;
      var DOM = Basis.DOM;
      var Data = Basis.Data;
      var CSS = Basis.CSS;
      var Event = Basis.Event;
      var Tester = Basis.Test.Tester;

      var nsWrappers = DOM.Wrapper;
      var Property = Basis.Data.Property.Property;
      var PropertySet = Basis.Data.Property.DataObjectSet;

      var CookieName;
      var TestProperty;

      var updateCount = 0;

      var testSet = [
        { info: { title: 'node0', value: 0, group: 1 } },
        { info: { title: 'node1', value: 1, group: 2 } },
        { info: { title: 'node2', value: 2, group: 1 } },
        { info: { title: 'node3', value: 3, group: 3 } },
        { info: { title: 'node4', value: 4, group: 4 } },
        { info: { title: 'node5', value: 5, group: 2 } },
        { info: { title: 'node6', value: 6, group: 2 } },
        { info: { title: 'node7', value: 7, group: 1 } },
        { info: { title: 'node8', value: 8, group: 3 } },
        { info: { title: 'node9', value: 9, group: 1 } }
      ];

      function nodeFactory(cfg){
        return new nsWrappers.Node(cfg);
      };

      function checkNode(node){
        if (node.firstChild != (node.childNodes[0] || null))
          return 'Wrong firstChild ref';
        if (node.lastChild != (node.childNodes[node.childNodes.length - 1] || null))
          return 'Wrong lastChild ref';

        for (var i = 0; i < node.childNodes.length; i++)
        {
          child = node.childNodes[i];
          if (child.parentNode != node)
            return 'child #' + i + ' has wrong parentNode ref';
          if (child.previousSibling != (node.childNodes[i - 1] || null))
            return 'child #' + i + ' has wrong previousSibling ref';
          if (child.nextSibling != (node.childNodes[i + 1] || null))
            return 'child #' + i + ' has wrong nextSibling ref';
          if (child.document != node.document)
            return 'child #' + i + ' has wrong document ref';
        }
        return false;
      }

      function $values(ar){
        return ar.map(function(node){
          return node.info.value + '(' + node.info.group + ')';
        })
      }

      return [
        {
          name: 'Property',
          testcase: [
            {
              name: 'create',
              test: function(){
                TestProperty = new Property(123);
                this.is(123, TestProperty.value);
              }
            },
            {
              name: 'addLink/removeLink',
              test: function(){


              }
            },
            {
              name: 'set #1',
              test: function(){
                var t = {};
                var value = Math.random();

                TestProperty.addLink(t, 'saved');
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(value, t.saved);

                // not fire on existing value set
                t.saved = 0;
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(0, t.saved);

                // fire on existing value set, with forced flag
                t.saved = 0;
                TestProperty.set(value, true);
                this.is(value, TestProperty.value);
                this.is(value, t.saved);

                TestProperty.clear();
              }
            },
            {
              name: 'set #2',
              test: function(){
                var t = {};
                var value = Math.random();
                TestProperty.addLink(t, 'saved');
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(value, t.saved);
                TestProperty.clear();

                var t = {};
                var value = Math.random();
                TestProperty.addLink(t, 'saved', '{0:.2}');
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(value.toFixed(2), t.saved);
                TestProperty.clear();

                var t = {};
                var value = Math.random();
                TestProperty.addLink(t, function(value){ this.saved = value * 2 });
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(value * 2, t.saved);
                TestProperty.clear();
              }
            },
            {
              name: 'set #3',
              test: function(){
                var t = DOM.createElement('DIV');
                var value = Math.random();
                TestProperty.addLink(t);
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(String(value), t.innerHTML);
                TestProperty.clear();

                var t = DOM.createElement('DIV');
                var value = Math.random();
                TestProperty.addLink(t, 'title');
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(String(value), t.title);
                TestProperty.clear();

                var t = DOM.createText('#text');
                var value = Math.random();
                TestProperty.addLink(t);
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(String(value), t.nodeValue);
                TestProperty.clear();

                var t = DOM.createText('#text');
                var value = Math.random();
                TestProperty.addLink(t, null, '{0:.2}');
                TestProperty.set(value);
                this.is(value, TestProperty.value);
                this.is(value.toFixed(2), t.nodeValue);
                TestProperty.clear();
              }
            },
            {
              name: 'get',
              test: function(){
              }
            }/*,
            {
              name: 'Property with proxy',
              test: function(){
                var a = new Property(0, null, Data.validator(function(value){ return !isNaN(value) && value }));
                a.set(3);
                this.is(3, a.value);
                a.set('hello');
                this.is(3, a.value);
              }
            }*/
          ]
        },
        {
          name: 'PropertySet',
          testcase: [
            {
              name: 'test #1',
              test: function(){
                s = new PropertySet();
                s.a = new Property(1);
                s.b = new Property(2);

                updateCount = 0;
                s.add(s.a);
                s.add(s.b);

                s.addHandler({
                  change: function(){
                    updateCount++;
                  }
                });

                s.a.set(11);
                s.b.set(11);

                this.is(0,0);

                s.a.set('test');
              }
            },
            {
              name: 'checkout',
              test: function(){
                this.is(1, updateCount);
                this.is('test', s.a.value);
                this.is(11, s.b.value);
              }
            },
            {
              name: 'destroyed property unlink',
              test: function(){
                s = new PropertySet();
                s.a = new Property(1);
                s.b = new Property(2);

                updateCount = 0;
                s.add(s.a);
                s.add(s.b);

                s.addHandler({
                  change: function(){
                    updateCount++;
                  }
                });

                this.is(2, s.objects.length);
                this.is(0, updateCount);

                s.a.destroy();

                this.is(1, s.objects.length);
                this.is(0, updateCount);
              }
            },
            {
              name: 'destroyed PropertySet unlink',
              test: function(){
                var result = 0;
                s = new PropertySet();
                s.a = new Property(1),
                s.b = new Property(2);

                s.addHandler({
                  change: function(){
                    result = a.value + b.value;
                  }
                });

                s.a.destroy();

                this.is(0, result);
              }
            }
          ]
        },
        {
          name: 'DOM wrappers',
          testcase: [
            {
              name: 'basic',
              testcase: [
                {
                  name: 'create',
                  test: function(){
                    var node = new nsWrappers.Node();
                    this.is(false, checkNode(node));

                    var node = new nsWrappers.Node({ info: { a: 1, b: 2 } });
                    this.is({ a: 1, b: 2}, node.info);
                  }
                },
                {
                  name: 'create with childNodes',
                  test: function(){
                    var node = new nsWrappers.Node({ childNodes: testSet.map(nodeFactory) });
                    this.is(false, checkNode(node));
                    this.is(testSet.length, node.childNodes.length);
                    this.is($values(testSet), $values(node.childNodes));

                    var node = new nsWrappers.Node({ childFactory: nodeFactory, childNodes: testSet });
                    this.is(false, checkNode(node));
                    this.is(testSet.length, node.childNodes.length);
                    this.is($values(testSet), $values(node.childNodes));
                  }
                },
                {
                  name: 'appendChild',
                  test: function(){
                    var node = new nsWrappers.Node();
                    for (var i = 0; i < testSet.length; i++)
                      node.appendChild(new nsWrappers.Node(testSet[i]));
                    this.is(false, checkNode(node));
                    this.is(testSet.length, node.childNodes.length);
                    this.is($values(testSet), $values(node.childNodes));
                  }
                },
                {
                  name: 'insertBefore',
                  test: function(){
                    var node = new nsWrappers.Node();
                    for (var i = 0; i < testSet.length; i++)
                      node.insertBefore(new nsWrappers.Node(testSet[i]));

                    this.is(false, checkNode(node));
                    this.is(testSet.length, node.childNodes.length);
                    this.is($values(testSet), $values(node.childNodes));

                    var node = new nsWrappers.Node();
                    for (var i = 0; i < testSet.length; i++)
                      node.insertBefore(new nsWrappers.Node(testSet[i]), node.firstChild);

                    this.is(false, checkNode(node));
                    this.is(testSet.length, node.childNodes.length);
                    this.is($values(testSet).reverse(), $values(node.childNodes));
                  }
                },
                {
                  name: 'DOM.insert',
                  test: function(){
                    var node = new nsWrappers.Node();
                    DOM.insert(node, testSet.map(nodeFactory))
                    this.is(false, checkNode(node));
                    this.is(testSet.length, node.childNodes.length);
                    this.is($values(testSet), $values(node.childNodes));

                    var node = new nsWrappers.Node({ childFactory: nodeFactory });
                    DOM.insert(node, testSet)
                    this.is(false, checkNode(node));
                    this.is(testSet.length, node.childNodes.length);
                    this.is($values(testSet), $values(node.childNodes));
                  }
                }
              ]
            },
            {
              name: 'localSorting',
              testcase: []
            },
            {
              name: 'localGrouping',
              testcase: [
                {
                  name: 'localGrouping in config',
                  test: function(){
                    var node = new nsWrappers.Node({
                      childFactory: nodeFactory,
                      localGrouping: 'info.group'
                    });

                    for (var i = 0; i < testSet.length; i++)
                      node.appendChild(testSet[i]);

                    this.is(false, checkNode(node));
                    this.is($values(testSet.sortAsObject('info.group')), $values(node.childNodes));

                    // =======================================
                    var node = new nsWrappers.Node({
                      childFactory: nodeFactory,
                      localGrouping: {
                        groupGetter: 'info.group',
                        localSorting: 'info.id',
                        localSortingDesc: true
                      }
                    });

                    for (var i = 0; i < testSet.length; i++)
                      node.appendChild(testSet[i]);

                    this.is(false, checkNode(node));
                    this.is($values([4, 3, 8, 1, 5, 6, 0, 2, 7, 9].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    // ======================================
                    var node = new nsWrappers.Node({
                      childFactory: nodeFactory,
                      localSorting: 'info.value',
                      localSortingDesc: true,
                      localGrouping: {
                        groupGetter: 'info.group',
                        localSorting: 'info.id',
                        localSortingDesc: true
                      },
                      childNodes: testSet
                    });

                    this.is(false, checkNode(node));
                    this.is($values([4, 8, 3, 6, 5, 1, 9, 7, 2, 0].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));
                  }
                },
                {
                  name: 'update PartitionNode',
                  test: function(){
                    // ======================================
                    var node = new nsWrappers.Node({
                      childFactory: nodeFactory,
                      localSorting: 'info.value',
                      localSortingDesc: true,
                      localGrouping: {
                        groupGetter: 'info.group',
                        localSorting: 'info.title',
                        localSortingDesc: true
                      },
                      childNodes: testSet
                    });

                    this.is(false, checkNode(node));
                    this.is($values([4, 8, 3, 6, 5, 1, 9, 7, 2, 0].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    var groups = Array.from(node.groupControl.childNodes);
                    /*for (var i = 0; i < groups.length; i++)
                      groups[i].update({ title: 'group' + i });*/

                    groups[0].update({ title: -4 });
                    this.is(false, checkNode(node));
                    this.is($values([8, 3, 6, 5, 1, 9, 7, 2, 0, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[1].update({ title: -3 });
                    this.is(false, checkNode(node));
                    this.is($values([6, 5, 1, 9, 7, 2, 0, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[2].update({ title: -2 });
                    this.is(false, checkNode(node));
                    this.is($values([9, 7, 2, 0, 6, 5, 1, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[3].update({ title: -1 });
                    this.is(false, checkNode(node));
                    this.is($values([9, 7, 2, 0, 6, 5, 1, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));
                  }
                },
                {
                  name: 'update PartitionNode with delegate',
                  test: function(){
                    var groupNodes = {};
                    for (var i = 1; i <= 4; i++)
                      groupNodes[i] = new nsWrappers.Node({
                        info: {
                          title: i
                        }
                      });

                    // ======================================
                    var node = new nsWrappers.Node({
                      childFactory: nodeFactory,
                      localSorting: 'info.value',
                      localSortingDesc: true,
                      localGrouping: {
                        groupGetter: Function.getter('info.group', groupNodes),
                        localSorting: 'info.title',
                        localSortingDesc: true
                      },
                      childNodes: testSet//.filter(Function.getter('info.group >= 3'))
                    });

                    this.is(false, checkNode(node));
                    this.is(4, node.groupControl.childNodes.length);
                    this.is($values([4, 8, 3, 6, 5, 1, 9, 7, 2, 0].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    var groups = Array.from(node.groupControl.childNodes);
                    /*for (var i = 0; i < groups.length; i++)
                      groups[i].update({ title: 'group' + i });*/

                    groups[0].update({ title: -4 });
                    this.is(false, checkNode(node));
                    this.is($values([8, 3, 6, 5, 1, 9, 7, 2, 0, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[1].update({ title: -3 });
                    this.is(false, checkNode(node));
                    this.is($values([6, 5, 1, 9, 7, 2, 0, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[2].update({ title: -2 });
                    this.is(false, checkNode(node));
                    this.is($values([9, 7, 2, 0, 6, 5, 1, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[3].update({ title: -1 });
                    this.is(false, checkNode(node));
                    this.is($values([9, 7, 2, 0, 6, 5, 1, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                  }
                },
                {
                  name: 'setLocalGrouping after create and update PartitionNode with delegate',
                  test: function(){

                    var groupNodes = {};
                    for (var i = 1; i <= 4; i++)
                      groupNodes[i] = new nsWrappers.Node({
                        info: {
                          title: i
                        }
                      });


                    var node = new nsWrappers.Node({
                      childFactory: nodeFactory,
                      localSorting: 'info.value',
                      localSortingDesc: true,
                      childNodes: testSet//.filter(Function.getter('info.group >= 3'))
                    });

                    this.is(false, checkNode(node));

                    node.setLocalGrouping({
                      groupGetter: Function.getter('info.group', groupNodes),
                      localSorting: 'info.title',
                      localSortingDesc: true
                    });

                    this.is(false, checkNode(node));
                    this.is(4, node.groupControl.childNodes.length);
                    this.is($values([4, 8, 3, 6, 5, 1, 9, 7, 2, 0].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    var groups = Array.from(node.groupControl.childNodes);
                    /*for (var i = 0; i < groups.length; i++)
                      groups[i].update({ title: 'group' + i });*/

                    groups[0].update({ title: -4 });
                    this.is(false, checkNode(node));
                    this.is($values([8, 3, 6, 5, 1, 9, 7, 2, 0, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[1].update({ title: -3 });
                    this.is(false, checkNode(node));
                    this.is($values([6, 5, 1, 9, 7, 2, 0, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[2].update({ title: -2 });
                    this.is(false, checkNode(node));
                    this.is($values([9, 7, 2, 0, 6, 5, 1, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));

                    groups[3].update({ title: -1 });
                    this.is(false, checkNode(node));
                    this.is($values([9, 7, 2, 0, 6, 5, 1, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));
                  }
                },
                {
                  name: 'setLocalGrouping after create and update PartitionNode with delegate & subscription',
                  test: function(){

                    var groupDelegateClass = Class(nsWrappers.Node, {
                      behaviour: {
                        update: function(){
                          if (this.subscriberCount)
                            this.update({ title: this.title_ });
                        },
                        subscribersChanged: function(){
                          if (this.subscriberCount)
                            this.update({ title: this.title_ });
                        }
                      },
                      init: function(config){
                        this.title_ = config.title;
                        this.inherit(config);
                      }
                    })

                    var groupNodes = {};
                    for (var i = 1; i <= 4; i++)
                      groupNodes[i] = new groupDelegateClass({
                        title: -i,
                        info: {
                          title: i
                        }
                      });


                    var node = new nsWrappers.Node({
                      childFactory: nodeFactory,
                      localSorting: 'info.value',
                      localSortingDesc: true,
                      childNodes: testSet//.filter(Function.getter('info.group >= 3'))
                    });

                    node.groupControlClass = Class(node.groupControlClass, {
                      childClass: Class(node.groupControlClass.prototype.childClass, {
                        isActiveSubscriber: true
                      })
                    });

                    this.is(false, checkNode(node));

                    node.setLocalGrouping({
                      groupGetter: Function.getter('info.group', groupNodes),
                      localSorting: 'info.title',
                      localSortingDesc: true
                    });

                    this.is(false, checkNode(node));
                    this.is(4, node.groupControl.childNodes.length);
                    this.is($values([9, 7, 2, 0, 6, 5, 1, 8, 3, 4].map(Function.getter(Function.$self, testSet))), $values(node.childNodes));
                  }
                }
              ]
            }
          ]
        }
      ];

    })());


  </script>
</body>

</html>